﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CommonLib {
    public class Plane : Primitive {
        //private Vector3c position;
        private double distance;
        private Vector3c direction;
        private Cell boundingBox;

        public Plane(Vector3c pos, Vector3c dir, bool li) {
            this.distance = -pos.dot(dir);
            this.direction = dir;
            this.direction.normalize();
            this.light = li;
            this.material = Material;
            this.boundingBox = new Cell(new Vector3c(-10000, -10000, -10000), new Vector3c(20000, 20000, 20000));
        }
        public override Orientation isIntersect(Ray r, ref double dist) {
            double nv = direction.dot(r.direction);
            if (Math.Abs(nv) < DoubleTester.Epsilon)
                return Orientation.Nonexistent;

            double nv0 = direction.dot(r.position);
            double t = -(nv0 + distance) / nv;
            if ((DoubleTester.Epsilon < t && t < dist) == false)
                return Orientation.Nonexistent;

            dist = t;
            if (nv < 0)
                return Orientation.Exterior;
            else
                return Orientation.Interior;
        }
        public override Vector3c getNormal(Vector3c bndry) {
            return direction;
        }
        public override Cell getBoundingBox() {
            return boundingBox;
        }
        public override Intersection isIntersect(Cell b) {
            Vector3c vmax, vmin;
            if (direction.x > 0) {
                vmax.x = b.vmax.x;
                vmin.x = b.vmin.x;
            } else {
                vmax.x = b.vmin.x;
                vmin.x = b.vmax.x;
            }
            if (direction.y > 0) {
                vmax.y = b.vmax.y;
                vmin.y = b.vmin.y;
            } else {
                vmax.y = b.vmin.y;
                vmin.y = b.vmax.y;
            }
            if (direction.z > 0) {
                vmax.z = b.vmax.z;
                vmin.z = b.vmin.z;
            } else {
                vmax.z = b.vmin.z;
                vmin.z = b.vmax.z;
            }
            if ((direction.dot(vmin) + distance) > 0)
                return Intersection.Outside;
            if ((direction.dot(vmax) + distance) < 0)
                return Intersection.Inside;
            return Intersection.Intersecting;
        }
        public override Vector3c getCenter() {
            Vector3c center = direction;
            center.mul(-distance);
            return center;
        }
    }
}
